﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using QQ2564874169.Core.Caching.Redis;
using QQ2564874169.Core.Utils;

namespace QQ2564874169.Core
{
    internal static class CoreExt
    {

        internal static DateTime ToDate(this long time, DateAccuracy accuracy = DateAccuracy.Second)
        {
            return ConvertHelper.ToDate(time, accuracy);
        }

        internal static long ToLongTime(this DateTime time, DateAccuracy accuracy = DateAccuracy.Second)
        {
            return ConvertHelper.ToLongTime(time, accuracy);
        }

        internal static T[] GetCustomAttributes<T>(this Type t, bool inherit = false)
        {
            return t.GetCustomAttributes(typeof(T), inherit).Cast<T>().ToArray();
        }

        internal static T GetCustomAttribute<T>(this Type t, bool inherit = false)
        {
            return t.GetCustomAttributes<T>(inherit).FirstOrDefault();
        }

        internal static void Add<TK, TV>(this IDictionary<TK, TV> source, IDictionary<TK, TV> args)
        {
            foreach (var k in args.Keys)
            {
                source.Add(k, args[k]);
            }
        }

        internal static object GetValue(this PropertyInfo property, object instance)
        {
            return property.GetValue(instance, null);
        }

        internal static void SetValue(this PropertyInfo property, object instance, object value)
        {
            property.SetValue(instance, value, null);
        }

        private static DateTime _startTime = new DateTime(1970, 1, 1).ToUniversalTime();

        internal static long ToLong(this DateTime time)
        {
            return (long)(time.ToUniversalTime() - _startTime).TotalMilliseconds;
        }

        internal static DateTime ToDateTime(this long time)
        {
            return _startTime.AddMilliseconds(time);
        }

        internal static TimeSpan? GetExpiry(this InternalCacheItem item, int? defaultExpiration)
        {
            TimeSpan? timeSpan = null;
            if (item.AbsoluteExpiration.HasValue)
            {
                var now = DateTime.Now;
                timeSpan = now.AddSeconds(item.AbsoluteExpiration.Value) - now;
            }
            else if (item.SlidingExpiration.HasValue)
            {
                timeSpan = TimeSpan.FromSeconds(item.SlidingExpiration.Value);
            }
            else if (defaultExpiration.HasValue)
            {
                timeSpan = TimeSpan.FromSeconds(defaultExpiration.Value);
            }
            return timeSpan;
        }

        internal static string GetAssemblyQualifiedName(this Type type)
        {
            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                return type.GetGenericArguments().First().AssemblyQualifiedName;
            }
            return type.AssemblyQualifiedName;
        }
    }
}
